<template>
    <div class="goods">
        <div class="common-layout">
            <el-container>
                <el-container>
                    <el-main>
                        <el-row>
                            <el-col>
                                <h4>商品信息</h4>
                                <div style="height: 400px; border: 1px solid #eee; margin-top: 20px">
                                    <el-auto-resizer>
                                        <template #default="{ height, width }">
                                            <el-table-v2
                                                :columns="columns"
                                                :data="data"
                                                :width="width"
                                                :height="height"
                                                fixed
                                            />
                                        </template>
                                    </el-auto-resizer>
                                </div>
                            </el-col>
                        </el-row>
                    </el-main>
                </el-container>
            </el-container>
        </div>
    </div>
</template>

<script lang="tsx" setup>
import {ref, withKeys} from 'vue'
import {ElInput, ElAutoResizer, ElTableV2} from 'element-plus'
import type {FunctionalComponent} from 'vue'
import type {Column, InputInstance} from 'element-plus'

type SelectionCellProps = {
    value: string
    intermediate?: boolean
    onChange: (value: string) => void
    onBlur: () => void
    onKeydownEnter: () => void
    forwardRef: (el: InputInstance) => void
}

const InputCell: FunctionalComponent<SelectionCellProps> = ({
                                                                value,
                                                                onChange,
                                                                onBlur,
                                                                onKeydownEnter,
                                                                forwardRef,
                                                            }) => {
    return (
        <ElInput
            ref={forwardRef as any}
            onInput={onChange}
            onBlur={onBlur}
            onKeydown={withKeys(onKeydownEnter, ['enter'])}
            modelValue={value}
        />
    )
}

const generateColumns = (length = 10, prefix = 'column-', props?: any) =>
    Array.from({length}).map((_, columnIndex) => ({
        ...props,
        key: `${prefix}${columnIndex}`,
        dataKey: `${prefix}${columnIndex}`,
        title: `Column ${columnIndex}`,
        editable: true,
        width: 150,
        cellRenderer: ({rowData, column}) => {
            const onChange = (value: string) => {
                rowData[column.dataKey!].value = value
            }
            const onEnterEditMode = () => {
                rowData[column.dataKey!].editing = true
            }
            const onExitEditMode = () => {
                rowData[column.dataKey!].editing = false
            }
            const input = ref()
            const setRef = (el) => {
                input.value = el
                if (el) {
                    el.focus?.()
                }
            }

            return rowData[column.dataKey!].editing ? (
                <InputCell
                    forwardRef={setRef}
                    value={rowData[column.dataKey!].value}
                    onChange={onChange}
                    onBlur={onExitEditMode}
                    onKeydownEnter={onExitEditMode}
                />
            ) : (
                <div class="table-v2-inline-editing-trigger" onClick={onEnterEditMode}>
                    {rowData[column.dataKey!].value}
                </div>
            )
        },
    }))

const generateData = (
    columns: ReturnType<typeof generateColumns>,
    length = 200,
    prefix = 'row-'
) =>
    Array.from({length}).map((_, rowIndex) => {
        return columns.reduce(
            (rowData, column, columnIndex) => {
                rowData[column.dataKey] = {
                    value: `Row ${rowIndex} - Col ${columnIndex}`,
                    editing: false
                }
                return rowData
            },
            {
                id: `${prefix}${rowIndex}`,
                parentId: null,
            }
        )
    })

const columns: Column<any>[] = generateColumns(10)


const data = ref(generateData(columns, 5))
</script>

<style>
.table-v2-inline-editing-trigger {
    border: 1px transparent dotted;
    padding: 4px;
}

.table-v2-inline-editing-trigger:hover {
    border-color: var(--el-color-primary);
}
</style>
